home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / SOURCE.ZIP / SWAP_P.ASM < prev    next >
Assembly Source File  |  1990-01-17  |  20KB  |  437 lines

  1. .model large
  2.  
  3. ;EXECSWAP.ASM
  4. ;  Swap memory and exec another program
  5. ;  Copyright (c) 1988 TurboPower Software
  6. ;  May be used freely as long as due credit is given
  7. ;-----------------------------------------------------------------------------
  8. ;DATA    SEGMENT BYTE PUBLIC
  9. .data
  10.         EXTRN   _BytesSwapped:DWORD      ;Bytes to swap to EMS/disk
  11.         EXTRN   _EmsAllocated:BYTE       ;True when EMS allocated for swap
  12.         EXTRN   _FileAllocated:BYTE      ;True when file allocated for swap
  13.         EXTRN   _EmsHandle:WORD          ;Handle of EMS allocation block
  14.         EXTRN   _FrameSeg:WORD           ;Segment of EMS page frame
  15.         EXTRN   _FileHandle:WORD         ;Handle of DOS swap file
  16.         EXTRN   _SwapName:BYTE           ;ASCIIZ name of swap file
  17.         EXTRN   _PrefixSeg:WORD          ;Base segment of program
  18. ;DATA    ENDS
  19. ;-----------------------------------------------------------------------------
  20. ;CODE    SEGMENT BYTE PUBLIC
  21. .code
  22. ;    ASSUME  CS:CODE,DS:DATA
  23.     PUBLIC  EXECWITHSWAP, _FIRSTTOSAVE
  24.     PUBLIC  ALLOCATESWAPFILE, DEALLOCATESWAPFILE
  25.     PUBLIC  EMSINSTALLED, EMSPAGEFRAME
  26.     PUBLIC  ALLOCATEEMSPAGES, DEALLOCATEEMSHANDLE
  27. ;-----------------------------------------------------------------------------
  28. FileAttr        EQU     0               ;Swap file attribute (hidden+system)
  29. EmsPageSize     EQU     16384           ;Size of EMS page
  30. FileBlockSize   EQU     32768           ;Size of a file block
  31. StkSize         EQU     128             ;Bytes in temporary stack
  32. lo              EQU     (WORD PTR 0)    ;Convenient typecasts
  33. hi              EQU     (WORD PTR 2)
  34. ofst            EQU     (WORD PTR 0)
  35. segm            EQU     (WORD PTR 2)
  36. ;-----------------------------------------------------------------------------
  37. ;Variables in CS
  38. EmsDevice       DB      'EMMXXXX0',0    ;Name of EMS device driver
  39. UsedEms         DB      0               ;1 if swapping to EMS, 0 if to file
  40. BytesSwappedCS  DD      0               ;Bytes to move during a swap
  41. EmsHandleCS     DW      0               ;EMS handle
  42. FrameSegCS      DW      0               ;Segment of EMS page window
  43. FileHandleCS    DW      0               ;DOS file handle
  44. PrefixSegCS     DW      0               ;Segment of base of program
  45. Status          DW      0               ;ExecSwap status code
  46. LeftToSwap      DD      0               ;Bytes left to move
  47. SaveSP          DW      0               ;Original stack pointer
  48. SaveSS          DW      0               ;Original stack segment
  49. PathPtr         DD      0               ;Pointer to program to execute
  50. CmdPtr          DD      0               ;Pointer to command line to execute
  51. ParasWeHave     DW      0               ;Paragraphs allocated to process
  52. CmdLine         DB      128 DUP(0)      ;Terminated command line passed to DOS
  53. Path            DB      64 DUP(0)       ;Terminated path name passed to DOS
  54. FileBlock1      DB      16 DUP(0)       ;FCB passed to DOS
  55. FileBlock2      DB      16 DUP(0)       ;FCB passed to DOS
  56. BooBoo          DB      '$'
  57. ComeBack        DB      '$'
  58. EnvironSeg      DW      0               ;Segment of environment for child
  59. CmdLinePtr      DD      0               ;Pointer to terminated command line
  60. FilePtr1        DD      0               ;Pointer to FCB file
  61. FilePtr2        DD      0               ;Pointer to FCB file
  62. TempStack       DB      StkSize DUP(0)  ;Temporary stack
  63. StackTop        LABEL   WORD            ;Initial top of stack
  64. ;-----------------------------------------------------------------------------
  65. ;Macros
  66. MovSeg          MACRO Dest,Src          ;Set one segment register to another
  67.         PUSH    Src
  68.         POP     Dest
  69.                 ENDM
  70.  
  71. MovMem          MACRO Dest,Src          ;Move from memory to memory via AX
  72.         MOV     AX,Src
  73.         MOV     Dest,AX
  74.                 ENDM
  75.  
  76. InitSwapCount   MACRO                   ;Initialize counter for bytes to swap
  77.     MovMem  LeftToSwap.lo,BytesSwappedCS.lo
  78.     MovMem  LeftToSwap.hi,BytesSwappedCS.hi
  79.                 ENDM
  80.  
  81. SetSwapCount    MACRO BlkSize           ;Return CX = bytes to move this block
  82.         LOCAL   FullBlk                 ;...and reduce total bytes left to move
  83.         MOV     CX,BlkSize              ;Assume we'll write a full block
  84.         CMP     LeftToSwap.hi,0         ;Is high word still non-zero?
  85.         JNZ     FullBlk                 ;Jump if so
  86.         CMP     LeftToSwap.lo,BlkSize   ;Low word still a block or more?
  87.         JAE     FullBlk                 ;Jump if so
  88.         MOV     CX,LeftToSwap.lo        ;Otherwise, move what's left
  89. FullBlk:SUB     LeftToSwap.lo,CX        ;Reduce number left to move
  90.         SBB     LeftToSwap.hi,0
  91.                 ENDM
  92.  
  93. NextBlock       MACRO SegReg, BlkSize   ;Point SegReg to next block to move
  94.         MOV     AX,SegReg
  95.         ADD     AX,BlkSize/16           ;Add paragraphs to next segment
  96.         MOV     SegReg,AX               ;Next block to move
  97.         MOV     AX,LeftToSwap.lo
  98.         OR      AX,LeftToSwap.hi        ;Bytes left to move?
  99.                 ENDM
  100.  
  101. EmsCall         MACRO FuncAH            ;Call EMM and prepare to check result
  102.         MOV     AH,FuncAH               ;Set up function
  103.         INT     67h
  104.         OR      AH,AH                   ;Error code in AH
  105.                 ENDM
  106.  
  107. DosCallAH       MACRO FuncAH            ;Call DOS subfunction AH
  108.         MOV     AH,FuncAH
  109.         INT     21h
  110.                 ENDM
  111.  
  112. DosCallAX       MACRO FuncAX            ;Call DOS subfunction AX
  113.         MOV     AX,FuncAX
  114.         INT     21h
  115.                 ENDM
  116.  
  117. InitSwapFile    MACRO
  118.         MOV     BX,FileHandleCS         ;BX = handle of swap file
  119.         XOR     CX,CX
  120.         XOR     DX,DX                   ;Start of file
  121.         DosCallAX 4200h                 ;DOS file seek
  122.                 ENDM
  123.  
  124. HaltWithError   MACRO Level             ;Halt if non-recoverable error occurs
  125.     PUSH    CS
  126.     POP    DS
  127.     MOV    DX,OFFSET BooBoo
  128.     MOV    AH,9
  129.     INT    21h
  130.         MOV     AL,Level                ;Set errorlevel
  131.         DosCallAH 4Ch
  132.                 ENDM
  133.  
  134. MoveFast        MACRO                   ;Move CX bytes from DS:SI to ES:DI
  135.         CLD                             ;Forward
  136.         RCR     CX,1                    ;Convert to words
  137.         REP     MOVSW                   ;Move the words
  138.         RCL     CX,1                    ;Get the odd byte, if any
  139.         REP     MOVSB                   ;Move it
  140.                 ENDM
  141.  
  142. SetTempStack    MACRO                   ;Switch to temporary stack
  143.         MOV     AX,OFFSET StackTop      ;Point to top of stack
  144.         MOV     BX,CS                   ;Temporary stack in this code segment
  145.         CLI                             ;Interrupts off
  146.         MOV     SS,BX                   ;Change stack
  147.         MOV     SP,AX
  148.         STI                             ;Interrupts on
  149.                 ENDM
  150. ;-----------------------------------------------------------------------------
  151. ;function ExecWithSwap(Path, CmdLine : string) : Word;
  152. EXECWITHSWAP   PROC FAR
  153.         PUSH    BP
  154.         MOV     BP,SP                   ;Set up stack frame
  155.  
  156. ;Move variables to CS where we can easily access them later
  157.         MOV     Status,1                ;Assume failure
  158.     LES     DI,[BP+6]               ;ES:DI -> CmdLine
  159.         MOV     CmdPtr.ofst,DI
  160.         MOV     CmdPtr.segm,ES          ;CmdPtr -> command line string
  161.     LES     DI,[BP+10]              ;ES:DI -> Path
  162.         MOV     PathPtr.ofst,DI
  163.         MOV     PathPtr.segm,ES         ;PathPtr -> path to execute
  164.         MOV     SaveSP,SP               ;Save stack position
  165.         MOV     SaveSS,SS
  166.     MovMem  BytesSwappedCS.lo,_BytesSwapped.lo
  167.     MovMem  BytesSwappedCS.hi,_BytesSwapped.hi
  168.         MovMem  EmsHandleCS,_EmsHandle
  169.         MovMem  FrameSegCS,_FrameSeg
  170.         MovMem  FileHandleCS,_FileHandle
  171.         MovMem  PrefixSegCS,_PrefixSeg
  172.         InitSwapCount                   ;Initialize bytes LeftToSwap
  173.  
  174. ;Check for swapping to EMS or file
  175.         CMP     _EmsAllocated,0          ;Check flag for EMS method
  176.         JZ      NotEms                  ;Jump if EMS not used
  177.         JMP     WriteE                  ;Swap to EMS
  178. NotEms: CMP     _FileAllocated,0         ;Check flag for swap file method
  179.         JNZ     WriteF                  ;Swap to file
  180.         JMP     ESDone                  ;Exit if no swapping method set
  181.  
  182. ;Write to swap file
  183. WriteF: MovSeg  DS,CS                   ;DS = CS
  184.         InitSwapFile                    ;Seek to start of swap file
  185.         JNC     EF0                     ;Jump if success
  186.         JMP     ESDone                  ;Exit if error
  187. EF0:    SetSwapCount FileBlockSize      ;CX = bytes to write
  188.     MOV     DX,OFFSET _FIRSTTOSAVE   ;DS:DX -> start of region to save
  189.         DosCallAH 40h                   ;File write
  190.         JC      EF1                     ;Jump if write error
  191.         CMP     AX,CX                   ;All bytes written?
  192.         JZ      EF2                     ;Jump if so
  193. EF1:    JMP     ESDone                  ;Exit if error
  194. EF2:    NextBlock DS,FileBlockSize      ;Point DS to next block to write
  195.         JNZ     EF0                     ;Loop if bytes left to write
  196.         MOV     UsedEms,0               ;Flag we used swap file for swapping
  197.         JMP     SwapDone                ;Done swapping out
  198.  
  199. ;Write to EMS
  200. WriteE: MOV     ES,_FrameSeg             ;ES -> page window
  201.     MOV     DX,_EmsHandle           ;DX = handle of our EMS block
  202.         XOR     BX,BX                   ;BX = initial logical page
  203.         MovSeg  DS,CS                   ;DS = CS
  204. EE0:    XOR     AL,AL                   ;Physical page 0
  205.         EmsCall 44h                     ;Map physical page
  206.         JZ      EE1                     ;Jump if success
  207.         JMP     ESDone                  ;Exit if error
  208. EE1:    SetSwapCount EmsPageSize        ;CX = Bytes to move
  209.         XOR     DI,DI                   ;ES:DI -> base of EMS page
  210.     MOV     SI,OFFSET _FIRSTTOSAVE   ;DS:SI -> region to save
  211.         MoveFast                        ;Move CX bytes from DS:SI to ES:DI
  212.         INC     BX                      ;Next logical page
  213.         NextBlock DS,EmsPageSize        ;Point DS to next page to move
  214.         JNZ     EE0                     ;Loop if bytes left to move
  215.         MOV     UsedEms,1               ;Flag we used EMS for swapping
  216.  
  217. ;Shrink memory allocated to this process
  218. SwapDone:MOV    AX,PrefixSegCS
  219.         MOV     ES,AX                   ;ES = segment of our memory block
  220.         DEC     AX
  221.         MOV     DS,AX                   ;DS = segment of memory control block
  222.         MOV     CX,DS:[0003h]           ;CX = current paragraphs owned
  223.         MOV     ParasWeHave,CX          ;Save current paragraphs owned
  224.         SetTempStack                    ;Switch to temporary stack
  225.     MOV     AX,OFFSET _FIRSTTOSAVE+15
  226.         MOV     CL,4
  227.         SHR     AX,CL                   ;Convert offset to paragraphs
  228.         ADD     BX,AX
  229.         SUB     BX,PrefixSegCS          ;BX = new paragraphs to keep
  230.         DosCallAH 4Ah                   ;SetBlock
  231.         JNC     EX0                     ;Jump if successful
  232.         JMP     EX5                     ;Swap back and exit
  233.  
  234. ;Set up parameters and call DOS Exec
  235. EX0:    MOV     AX,ES:[002Ch]           ;Get environment segment
  236.         MOV     EnvironSeg,AX
  237.         MovSeg  ES,CS                   ;ES = CS
  238.         LDS     SI,PathPtr              ;DS:SI -> path to execute
  239.         MOV     DI,OFFSET Path          ;ES:DI -> local ASCIIZ copy
  240.         CLD
  241. ;    LODSB                           ;Read current length
  242. ;    CMP     AL,63                   ;Truncate if exceeds space set aside
  243. ;    JB      EX1
  244. ;    MOV     AL,63
  245. ;EX1:    MOV     CL,AL
  246. ;    XOR     CH,CH                   ;CX = bytes to copy
  247.     MOV     CX, 63
  248.         REP     MOVSB
  249. ;    XOR     AL,AL
  250. ;    STOSB                           ;ASCIIZ terminate
  251.         LDS     SI,CmdPtr               ;DS:SI -> Command line to pass
  252.         MOV     DI,OFFSET CmdLine       ;ES:DI -> Local terminated copy
  253. ;    LODSB
  254. ;    CMP     AL,126                  ;Truncate command if exceeds space
  255. ;    JB      EX2
  256. ;    MOV     AL,126
  257. ;EX2:    STOSB
  258. ;    MOV     CL,AL
  259. ;    XOR     CH,CH                   ;CX = bytes to copy
  260.     MOV     CX, 127
  261.         REP     MOVSB
  262. ;    MOV     AL,0DH                  ;Terminate with ^M
  263. ;    STOSB
  264.  
  265.         MovSeg  DS,CS                   ;DS = CS
  266.     MOV     SI,OFFSET CmdLine
  267.     MOV     CmdLinePtr.ofst,SI
  268.     MOV     CmdLinePtr.segm,DS      ;Store pointer to command line
  269. ;       INC     SI
  270.     MOV     DI,OFFSET FileBlock1
  271.     MOV     FilePtr1.ofst,DI
  272.     MOV     FilePtr1.segm,ES        ;Store pointer to filename 1, if any
  273.     DosCallAX 2901h                 ;Parse FCB
  274.     MOV     DI,OFFSET FileBlock2
  275.     MOV     FilePtr2.ofst,DI
  276.     MOV     FilePtr2.segm,ES        ;Store pointer to filename 2, if any
  277.     DosCallAX 2901h                 ;Parse FCB
  278.     MOV     DX,OFFSET Path
  279.     MOV     BX,OFFSET EnvironSeg
  280.         DosCallAX 4B00h                 ;Exec
  281.         JC      EX3                     ;Jump if error in DOS call
  282.         XOR     AX,AX                   ;Return zero for success
  283. EX3:    MOV     Status,AX               ;Save DOS error code
  284.  
  285. ;Set up temporary stack and reallocate original memory block
  286.         SetTempStack                    ;Set up temporary stack
  287.         MOV     ES,PrefixSegCS
  288.         MOV     BX,ParasWeHave
  289.         DosCallAH 4Ah                   ;SetBlock
  290.         JNC     EX4                     ;Jump if no error
  291.         HaltWithError 0FFh              ;Must halt if failure here
  292. EX4:    InitSwapCount                   ;Initialize LeftToSwap
  293.  
  294. ;Check which swap method is in use
  295. EX5:    PUSH    CS
  296.     POP    DS
  297.     MOV    DX,OFFSET ComeBack
  298.     MOV    AH,9
  299.     INT    21h
  300.     CMP     UsedEms,0
  301.         JZ      ReadF                   ;Jump to read back from file
  302.         JMP     ReadE                   ;Read back from EMS
  303.  
  304. ;Read back from swap file
  305. ReadF:  MovSeg  DS,CS                   ;DS = CS
  306.         InitSwapFile                    ;Seek to start of swap file
  307.         JNC     EF3                     ;Jump if we succeeded
  308.         HaltWithError 0FEh              ;Must halt if failure here
  309. EF3:    SetSwapCount FileBlockSize      ;CX = bytes to read
  310.     MOV     DX,OFFSET _FIRSTTOSAVE   ;DS:DX -> start of region to restore
  311.         DosCallAH 3Fh                   ;Read file
  312.         JNC     EF4                     ;Jump if no error
  313.         HaltWithError 0FEh              ;Must halt if failure here
  314. EF4:    CMP     AX,CX
  315.         JZ      EF5                     ;Jump if full block read
  316.         HaltWithError 0FEh              ;Must halt if failure here
  317. EF5:    NextBlock DS,FileBlockSize      ;Point DS to next page to read
  318.         JNZ     EF3                     ;Jump if bytes left to read
  319.         JMP     ESDone                  ;We're done
  320.  
  321. ;Copy back from EMS
  322. ReadE:  MOV     DS,FrameSegCS           ;DS -> page window
  323.         MOV     DX,EmsHandleCS          ;DX = handle of our EMS block
  324.         XOR     BX,BX                   ;BX = initial logical page
  325.         MovSeg  ES,CS                   ;ES = CS
  326. EE3:    XOR     AL,AL                   ;Physical page 0
  327.         EmsCall 44h                     ;Map physical page
  328.         JZ      EE4                     ;Jump if success
  329.         HaltWithError 0FDh              ;Must halt if failure here
  330. EE4:    SetSwapCount EmsPageSize        ;CX = Bytes to move
  331.         XOR     SI,SI                   ;DS:SI -> base of EMS page
  332.     MOV     DI,OFFSET _FIRSTTOSAVE   ;ES:DI -> region to restore
  333.         MoveFast                        ;Move CX bytes from DS:SI to ES:DI
  334.         INC     BX                      ;Next logical page
  335.         NextBlock ES,EmsPageSize        ;Point ES to next page to move
  336.         JNZ     EE3                     ;Jump if so
  337.  
  338. ESDone: CLI                             ;Switch back to original stack
  339.         MOV     SS,SaveSS
  340.         MOV     SP,SaveSP
  341.         STI
  342.     MOV     AX,SEG DGROUP
  343.         MOV     DS,AX                   ;Restore DS
  344.         MOV     AX,Status               ;Return status
  345.         POP     BP
  346.     RET     8                       ;Remove parameters and return
  347. EXECWITHSWAP   ENDP
  348. ;-----------------------------------------------------------------------------
  349. ;Label marks first location to swap
  350. _FIRSTTOSAVE:
  351. ;-----------------------------------------------------------------------------
  352. ;function AllocateSwapFile : Boolean;
  353. ALLOCATESWAPFILE PROC FAR
  354.         MOV     CX,FileAttr             ;Attribute for swap file
  355.         MOV     DX,OFFSET _SwapName     ;DS:DX -> ASCIIZ swap name
  356.         DosCallAH 3Ch                   ;Create file
  357.         MOV     _FileHandle,AX           ;Save handle assuming success
  358.         MOV     AL,0                    ;Assume failure
  359.         JC      ASDone                  ;Failed if carry set
  360.         INC     AL                      ;Return true for success
  361. ASDone: RET
  362. ALLOCATESWAPFILE ENDP
  363.  
  364. ;-----------------------------------------------------------------------------
  365. ;procedure DeallocateSwapFile;
  366. DEALLOCATESWAPFILE PROC FAR
  367.         MOV     BX,_FileHandle           ;Handle of swap file
  368.         DosCallAH 3Eh                   ;Close file
  369.         XOR     CX,CX                   ;Normal attribute
  370.         MOV     DX,OFFSET _SwapName     ;DS:DX -> ASCIIZ swap name
  371.         DosCallAX 4301h                 ;Set file attribute
  372.         DosCallAH 41h                   ;Delete file
  373.         RET
  374. DEALLOCATESWAPFILE ENDP
  375.  
  376. ;-----------------------------------------------------------------------------
  377. ;function EmsInstalled : Boolean;
  378. EMSINSTALLED    PROC FAR
  379.  
  380.         PUSH    DS
  381.         MovSeg  DS,CS                   ;DS = CS
  382.         MOV     DX,OFFSET EmsDevice     ;DS:DX -> EMS driver name
  383.         DosCallAX 3D02h                 ;Open for read/write
  384.         POP     DS
  385.         MOV     BX,AX                   ;Save handle in case one returned
  386.         MOV     AL,0                    ;Assume FALSE
  387.         JC      EIDone
  388.     DosCallAH 3Eh                   ;Close file
  389.     MOV     AL,1                    ;Return TRUE
  390.  
  391. EIDone: RET
  392.  
  393. EMSINSTALLED    ENDP
  394.  
  395. ;-----------------------------------------------------------------------------
  396. ;function EmsPageFrame : Word;
  397. EMSPAGEFRAME    PROC FAR
  398.  
  399.         EmsCall 41h                     ;Get page frame
  400.         MOV     AX,BX                   ;AX = segment
  401.         JZ      EPDone                  ;Done if Error = 0
  402.     XOR     AX,AX                   ;Else segment = 0
  403.  
  404. EPDone: RET
  405.  
  406. EMSPAGEFRAME    ENDP
  407.  
  408. ;-----------------------------------------------------------------------------
  409. ;function AllocateEmsPages(NumPages : Word) : Word;
  410. ALLOCATEEMSPAGES PROC FAR
  411.  
  412.         MOV     BX,SP                   ;Set up stack frame
  413.         MOV     BX,SS:[BX+4]            ;BX = NumPages
  414.         EmsCall 43h                     ;Allocate EMS
  415.         MOV     AX,DX                   ;Assume success
  416.         JZ      APDone                  ;Done if not 0
  417.     MOV     AX,0FFFFh               ;$FFFF for failure
  418.  
  419. APDone:    RET     2                       ;Remove parameter and return
  420.  
  421. ALLOCATEEMSPAGES ENDP
  422.  
  423. ;-----------------------------------------------------------------------------
  424. ;procedure DeallocateEmsHandle(Handle : Word);
  425. DEALLOCATEEMSHANDLE PROC FAR
  426.  
  427.         MOV     BX,SP                   ;Set up stack frame
  428.         MOV     DX,SS:[BX+4]            ;DX = Handle
  429.     EmsCall 45h                     ;Deallocate EMS
  430.  
  431.     RET     2                       ;Remove parameter and return
  432.  
  433. DEALLOCATEEMSHANDLE ENDP
  434.  
  435. ;CODE    ENDS
  436.         END
  437.